package com.shenda.api.service.impl;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.Arrays;

import org.springframework.beans.factory.annotation.Autowired;

import com.shenda.api.dao.DatasDao;
import com.shenda.api.dto.UploadDTO;
import com.shenda.api.entity.Data;
import com.shenda.api.service.DatasService;
import com.shenda.device.Constants;
import com.shenda.device.Device;
import com.shenda.device.analysis.Analysis;
import com.shenda.device.analysis.AnalysisQuery;
import com.shenda.device.analysis.AnalysisResult;
import com.shenda.device.analysis.FileAccesser;
import com.shenda.device.analysis.protocol.AdaptProtpcol;
import com.shenda.device.analysis.protocol.Protpcol;
import com.shenda.device.message.RespMsg_UploadStart;
import com.shenda.starter.config.Settings;
import com.swak.annotation.Context;
import com.swak.annotation.FluxService;
import com.swak.entity.Page;
import com.swak.entity.Parameters;
import com.swak.persistence.QueryCondition;
import com.swak.utils.IOUtils;

/**
 * 数据服务 -- 顺序的操作
 * 
 * @author lifeng
 */
@FluxService(context = Context.Order)
public class DatasServiceImpl implements DatasService {

	@Autowired
	private DatasDao datasDao;
	private FileAccesser fileAccesser;

	/**
	 * 得到
	 */
	@Override
	public AnalysisResult get(String id) {

		// 实际的数据
		Data data = this.datasDao.get(id);

		// 返回分析结果
		return new AnalysisResult().setGyro(data.getGyro()).setGyroName(data.getGyroName())
				.setStartTime(data.getStartTime()).setEndTime(data.getEndTime()).setCjms(data.getCjms())
				.setCjpl(data.getCjpl()).setOdr(data.getOdr()).setTotal(data.getTotal()).setFrames(data.getFrames())
				.setTimes(data.getTimes());
	}

	/**
	 * 删除数据
	 */
	@Override
	public void delete(String id) {

		// 实际的数据
		Data data = this.datasDao.get(id);

		// 数据文件
		File datFile = new File(Settings.me().getDataPath(), data.getGyroName() + "/" + data.getName());

		// 文件分析器
		Analysis analysis = Analysis.newAnalysis(data.getCjms(), datFile);

		// 删除分析文件
		this.deleteFile(analysis.getAnalysisFile());

		// 删除数据文件
		datFile.delete();

		// 删除数据文件
		this.datasDao.delete(data);
	}

	// 删除整个文件夹
	protected boolean deleteFile(File dirFile) {
		if (!dirFile.exists()) {
			return false;
		}
		if (dirFile.isFile()) {
			return dirFile.delete();
		} else {
			for (File file : dirFile.listFiles()) {
				deleteFile(file);
			}
		}
		return dirFile.delete();
	}

	/**
	 * 分页显示数据
	 */
	@Override
	public Page page(Data data, Parameters param) {
		QueryCondition query = new QueryCondition();
		query.setOrderByClause("STARTTIME DESC");
		return datasDao.page(query, param);
	}

	/**
	 * 存储
	 */
	@Override
	public void save(Data data) {
		datasDao.insert(data);
	}

	/**
	 * 图表展示数据
	 */
	@Override
	public AnalysisResult chart(AnalysisQuery query) {

		// 实际的数据
		Data data = this.datasDao.get(query.getId());

		// 数据文件
		File datFile = new File(Settings.me().getDataPath(), data.getGyroName() + "/" + data.getName());

		// 文件分析器
		Analysis analysis = Analysis.newAnalysis(data.getCjms(), datFile);

		// 最新的数据访问器
		this.fileAccesser = FileAccesser.newFileAccesser(fileAccesser, analysis.getAnalysisFile());

		// 分析结果
		AnalysisResult result = analysis.doAnalysis(query.setFastAccess(this.fileAccesser));

		// 返回分析结果
		return result.setGyro(data.getGyro()).setGyroName(data.getGyroName()).setStartTime(data.getStartTime())
				.setEndTime(data.getEndTime()).setCjms(data.getCjms()).setCjpl(data.getCjpl()).setOdr(data.getOdr())
				.setTotal(data.getTotal()).setFrames(data.getFrames()).setTimes(data.getTimes());
	}

	/**
	 * 导入文件进行分析
	 * 
	 * @param datas
	 * @return
	 */
	@Override
	public AnalysisResult upload(UploadDTO upload) {

		// 创建数据
		ByteArrayInputStream bis = new ByteArrayInputStream(upload.getDatas());

		try {

			// 数据解析的协议
			Protpcol protpcol = new AdaptProtpcol();

			// 读取头部
			byte[] head = protpcol.readHead(bis);

			// 解析头部数据
			RespMsg_UploadStart headMsg = (RespMsg_UploadStart) new RespMsg_UploadStart().parse(head);

			// 存储文件
			Device device = new Device();
			device.setMac(upload.getMac());
			device.uploadStart(headMsg);
			byte[] cache = new byte[Constants.iBlockSize];
			int size = -1;
			while ((size = bis.read(cache)) != -1) {
				device.uploadData(Arrays.copyOfRange(cache, 0, size));
			}
			device.forceStop();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(bis);
		}
		return new AnalysisResult();
	}
}
